package com.exam.api.modules.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.exam.api.common.Const;
import com.exam.api.modules.system.domain.TblRole;
import com.exam.api.modules.system.domain.TblRoleMenu;
import com.exam.api.modules.system.dto.RoleAddDTO;
import com.exam.api.modules.system.dto.RoleIdDTO;
import com.exam.api.modules.system.dto.RolePageDTO;
import com.exam.api.modules.system.dto.RoleUpdateDTO;
import com.exam.api.modules.system.event.RoleDeleteEvent;
import com.exam.api.modules.system.mapper.TblRoleMapper;
import com.exam.api.modules.system.service.TblRoleMenuService;
import com.exam.api.modules.system.service.TblRoleService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 角色逻辑接口类实现类
 *
 * @author bcheng
 */
@Service
public class TblRoleServiceImpl extends ServiceImpl<TblRoleMapper, TblRole> implements TblRoleService {

    @Resource
    private TblRoleMenuService tblRoleMenuService;
    @Resource
    private ApplicationContext applicationContext;

    @Override
    public List<TblRole> listRoles(long userId) {
        return baseMapper.listRoles(userId);
    }

    @Override
    public List<Long> listRoleIdsByUserId(long userId) {
        return baseMapper.listRoleIdsByUserId(userId);
    }

    @Override
    public List<String> listRoleCodes(Long userId) {
        if (userId == null) {
            return ListUtil.empty();
        }
        return baseMapper.listRoleCodes(userId);
    }

    @Override
    public Page<TblRole> pageRole(RolePageDTO dto) {
        Page<TblRole> page = lambdaQuery()
                .like(StrUtil.isNotBlank(dto.getKeyword()), TblRole::getName, dto.getKeyword())
                .eq(TblRole::getIsDelete, Const.ZERO)
                .page(Page.of(dto.getPageNum(), dto.getPageSize()));
        return page;
    }

    @Override
    public TblRole getRole(RoleIdDTO dto) {
        TblRole one = getById(dto.getRoleId());
        one.setMenuIds(ListUtil.empty());
        List<TblRoleMenu> list = tblRoleMenuService.lambdaQuery()
                .eq(TblRoleMenu::getRoleId, dto.getRoleId())
                .select(TblRoleMenu::getMenuId)
                .list();
        if (CollUtil.isNotEmpty(list)) {
            List<Long> menuIds = list.stream().map(TblRoleMenu::getMenuId).toList();
            one.setMenuIds(menuIds);
        }
        return one;
    }

    @Override
    public void addRole(RoleAddDTO dto) {
        TblRole role = dto.converter();
        save(role);
        tblRoleMenuService.saveRoleMenu(role.getRoleId(), dto.getMenuIds());
    }

    @Override
    public void updateRole(RoleUpdateDTO dto) {
        updateById(dto.converter());
        tblRoleMenuService.saveRoleMenu(dto.getRoleId(), dto.getMenuIds());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(RoleIdDTO dto) {
        removeById(dto.getRoleId());
        //发送删除角色事件
        applicationContext.publishEvent(new RoleDeleteEvent(dto.getRoleId()));
    }
}
